package com.wechat.gateway.ratelimit;

import jakarta.annotation.PostConstruct;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * 限流规则管理器
 */
@Slf4j
@Component
@ConfigurationProperties(prefix = "rate-limit")
public class RateLimitRuleManager {

    private final AntPathMatcher pathMatcher = new AntPathMatcher();
    @Setter
    @Getter
    private List<RateLimitConfig> rules = new ArrayList<>();

    @PostConstruct
    public void init() {
        log.info("加载限流规则配置，共{}条规则", rules.size());
        for (RateLimitConfig rule : rules) {
            log.info("限流规则: {} - {} {} - 容量:{}, 速率:{}/s",
                    rule.getRuleName(),
                    rule.getMethod() != null ? rule.getMethod() : "ALL",
                    rule.getPathPattern(),
                    rule.getCapacity(),
                    rule.getRefillRate());
        }
    }

    /**
     * 根据请求路径和方法匹配限流规则
     */
    public Optional<RateLimitConfig> matchRule(String path, String method) {
        return rules.stream()
                .filter(RateLimitConfig::isEnabled)
                .filter(rule -> matchPath(rule.getPathPattern(), path))
                .filter(rule -> matchMethod(rule.getMethod(), method))
                .findFirst();
    }

    /**
     * 获取所有规则
     */
    public List<RateLimitConfig> getAllRules() {
        return new ArrayList<>(rules);
    }

    /**
     * 添加规则
     */
    public void addRule(RateLimitConfig rule) {
        rules.add(rule);
        log.info("添加限流规则: {}", rule.getRuleName());
    }

    /**
     * 移除规则
     */
    public boolean removeRule(String ruleName) {
        boolean removed = rules.removeIf(rule -> rule.getRuleName().equals(ruleName));
        if (removed) {
            log.info("移除限流规则: {}", ruleName);
        }
        return removed;
    }

    /**
     * 更新规则
     */
    public boolean updateRule(RateLimitConfig newRule) {
        for (int i = 0; i < rules.size(); i++) {
            if (rules.get(i).getRuleName().equals(newRule.getRuleName())) {
                rules.set(i, newRule);
                log.info("更新限流规则: {}", newRule.getRuleName());
                return true;
            }
        }
        return false;
    }

    /**
     * 启用/禁用规则
     */
    public boolean toggleRule(String ruleName, boolean enabled) {
        for (RateLimitConfig rule : rules) {
            if (rule.getRuleName().equals(ruleName)) {
                rule.setEnabled(enabled);
                log.info("{}限流规则: {}", enabled ? "启用" : "禁用", ruleName);
                return true;
            }
        }
        return false;
    }

    /**
     * 路径匹配
     */
    private boolean matchPath(String pattern, String path) {
        return pathMatcher.match(pattern, path);
    }

    /**
     * HTTP方法匹配
     */
    private boolean matchMethod(String ruleMethod, String requestMethod) {
        return ruleMethod == null || "*".equals(ruleMethod) || ruleMethod.equalsIgnoreCase(requestMethod);
    }

}